home *** CD-ROM | disk | FTP | other *** search
- /* Chown command -- for the Midnight Commander
- Copyright (C) 1994 Radek Doulik
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
- #include <config.h>
- #include <string.h>
- #include <stdio.h>
- #include <stdlib.h> /* For malloc() */
-
- #include <sys/types.h>
- #include <sys/param.h>
- #include <sys/stat.h>
- #include <grp.h>
- #include <pwd.h>
- #ifdef HAVE_UNISTD_H
- # include <unistd.h>
- #endif
-
- #include "tty.h"
- #include "mad.h"
- #include "util.h" /* Needed for the externs */
- #include "win.h"
- #include "color.h"
- #include "dlg.h"
- #include "widget.h"
- #include "dialog.h" /* For do_refresh() */
-
- /* Needed for the extern declarations of integer parameters */
- #include "dir.h"
- #include "panel.h" /* Needed for the externs */
- #include "file.h"
- #include "chmod.h"
- #include "main.h"
- #include "chown.h"
- #include "wtools.h" /* For init_box_colors */
-
- #define UX 5
- #define UY 2
-
- #define GX 27
- #define GY 2
-
- #define BX 5
- #define BY 15
-
- #define TX 50
- #define TY 2
-
- #define BUTTONS 5
-
- #define B_SETALL B_USER
- #define B_SETUSR B_USER + 1
- #define B_SETGRP B_USER + 2
-
- /* struct stat *sf_stat; */
- static int need_update, end_chown;
- static int current_file;
- static int single_set;
- static WListbox *l_user, *l_group;
-
- static struct {
- int ret_cmd, y, x;
- char *text;
- int hkey, hpos;
- } chown_but[BUTTONS] = {
- { B_CANCEL, 0, 54, "[ Cancel ]", 'c', 2, },
- { B_ENTER, 0, 45, "[ Set ]", 's', 2, },
- { B_SETUSR, 0, 29, "[ Set users ]", 'u', 6, },
- { B_SETGRP, 0, 13, "[ Set groups ]", 'g', 6, },
- { B_SETALL, 0, 0, "[ Set all ]", 'a', 6, },
- };
-
- #define LABELS 5
- static struct {
- int y, x;
- WLabel *l;
- } chown_label [LABELS] = {
- { TY+2, TX+2 },
- { TY+4, TX+2 },
- { TY+6, TX+2 },
- { TY+8, TX+2 },
- { TY+10,TX+2 }
- };
-
- #ifndef HAVE_X
- static void chown_refresh (void)
- {
- attrset (REVERSE_COLOR);
- dlg_erase (ch_dlg);
-
- draw_box (ch_dlg, 1, 2, 16, 70);
- draw_box (ch_dlg, UY, UX, 12, 21);
- draw_box (ch_dlg, GY, GX, 12, 21);
- draw_box (ch_dlg, TY, TX, 12, 19);
-
- attrset (COLOR_NORMAL);
- dlg_move (ch_dlg, TY + 1, TX + 1);
- addstr (" Name ");
- dlg_move (ch_dlg, TY + 3, TX + 1);
- addstr (" Owner name ");
- dlg_move (ch_dlg, TY + 5, TX + 1);
- addstr (" Group name ");
- dlg_move (ch_dlg, TY + 7, TX + 1);
- addstr (" Size ");
- dlg_move (ch_dlg, TY + 9, TX + 1);
- addstr (" Permission ");
-
- attrset (COLOR_HOT_NORMAL);
- dlg_move (ch_dlg, 1, 28);
- addstr (" Chown command ");
- dlg_move (ch_dlg, UY, UX + 1);
- addstr (" User name ");
- dlg_move (ch_dlg, GY, GX + 1);
- addstr (" Group name ");
- dlg_move (ch_dlg, TY, TX + 1);
- addstr (" File ");
- }
- #endif
-
- static char *next_file (void)
- {
- while (!cpanel->dir.list[current_file].f.marked)
- current_file++;
-
- return cpanel->dir.list[current_file].fname;
- }
-
- static int chown_callback (Dlg_head * h, int Par, int Msg)
- {
- switch (Msg) {
- #ifndef HAVE_X
- case DLG_DRAW:
- chown_refresh ();
- break;
- #endif
- }
- return 0;
- }
-
- static int l_call (void *data)
- {
- return 1;
- }
-
- static void init_chown (void)
- {
- int i;
- struct passwd *l_pass;
- struct group *l_grp;
-
- do_refresh ();
- end_chown = need_update = current_file = 0;
- single_set = (cpanel->marked < 2) ? 3 : 0;
-
- ch_dlg = create_dlg (0, 0, 18, 74, dialog_colors, chown_callback,
- "[Chown]", "chown", DLG_CENTER);
-
- #define XTRACT(i) BY+chown_but[i].y, BX+chown_but[i].x, chown_but[i].ret_cmd, chown_but[i].text, chown_but[i].hkey, chown_but[i].hpos, 0, 0
-
- tk_new_frame (ch_dlg, "b.");
- for (i = 0; i < BUTTONS-single_set; i++)
- add_widget (ch_dlg, button_new (XTRACT (i)));
-
- /* Add the widgets for the file information */
- #define LX(i) chown_label [i].y, chown_label [i].x, ""
- tk_new_frame (ch_dlg, "l.");
- for (i = 0; i < LABELS; i++){
- chown_label [i].l = label_new (LX (i));
- add_widget (ch_dlg, chown_label [i].l);
- }
-
- /* get new listboxes */
- l_user = listbox_new (UY + 1, UX + 1, 19, 10, 0, l_call);
- l_group = listbox_new (GY + 1, GX + 1, 19, 10, 0, l_call);
-
- listbox_add_item (l_user, 0, 0, "<Unknown user>", NULL); /* add fields for unknown names (numbers) */
- listbox_add_item (l_group, 0, 0, "<Unknown group>", NULL);
-
- setpwent (); /* get and put user names in the listbox */
- while ((l_pass = getpwent ())) {
- listbox_add_item (l_user, 0, 0, l_pass->pw_name, NULL);
- }
-
- setgrent (); /* get and put group names in the listbox */
- while ((l_grp = getgrent ())) {
- listbox_add_item (l_group, 0, 0, l_grp->gr_name, NULL);
- }
-
- tk_new_frame (ch_dlg, "f.");
- add_widget (ch_dlg, l_group);
- tk_new_frame (ch_dlg, "g.");
- add_widget (ch_dlg, l_user); /* add listboxes to the dialogs */
- tk_end_frame ();
- }
-
- void chown_done (void)
- {
- if (need_update)
- update_panels (UP_OPTIMIZE, UP_KEEPSEL, UP_KEEPSEL);
- repaint_screen ();
- }
-
- static inline void do_chown (uid_t u, gid_t g)
- {
- chown (cpanel->dir.list [current_file].fname, u, g);
- file_mark (cpanel, current_file, 0);
- }
-
- static void apply_chowns (uid_t u, gid_t g)
- {
- char *fname;
-
- need_update = end_chown = 1;
- do_chown (u,g);
- cpanel->marked--;
-
- do {
- fname = next_file ();
-
- do_chown (u,g);
- cpanel->marked--;
- } while (cpanel->marked);
- }
-
- #define chown_label(n,txt) label_set_text (chown_label [n].l, txt)
-
- void chown_cmd (void)
- {
- char *fname;
- struct stat sf_stat;
- WLEntry *fe;
- uid_t new_user;
- gid_t new_group;
- char buffer [15];
-
- do { /* do while any files remaining */
- init_chown ();
- new_user = new_group = -1;
-
- if (cpanel->marked)
- fname = next_file (); /* next marked file */
- else
- fname = selection (cpanel)->fname; /* single file */
-
- if (!stat_file (fname, &sf_stat)) /* get status of file */
- break;
-
- /* select in listboxes */
- fe = listbox_search_text (l_user, get_owner(sf_stat.st_uid));
- if (fe)
- listbox_select_entry (l_user, fe);
-
- fe = listbox_search_text (l_group, get_group(sf_stat.st_gid));
- if (fe)
- listbox_select_entry (l_group, fe);
-
- chown_label (0, name_trunc (fname, 15));
- chown_label (1, name_trunc (get_owner (sf_stat.st_uid), 15));
- chown_label (2, name_trunc (get_group (sf_stat.st_gid), 15));
- sprintf (buffer, "%d", c_fsize);
- chown_label (3, buffer);
- chown_label (4, string_perm (sf_stat.st_mode));
-
- run_dlg (ch_dlg);
-
- switch (ch_dlg->ret_value) {
- case B_CANCEL:
- end_chown = 1;
- break;
-
- case B_SETUSR:
- {
- struct passwd *user;
-
- user = getpwnam (l_user->current->text);
- if (user){
- new_user = user->pw_uid;
- apply_chowns (new_user, new_group);
- }
- break;
- }
- case B_SETGRP:
- {
- struct group *grp;
-
- grp = getgrnam (l_group->current->text);
- if (grp){
- new_group = grp->gr_gid;
- apply_chowns (new_user, new_group);
- }
- break;
- }
- case B_SETALL:
- case B_ENTER:
- new_group = (getgrnam (l_group->current->text))->gr_gid;
- new_user = (getpwnam (l_user->current->text))->pw_uid;
- if (ch_dlg->ret_value==B_ENTER) {
- need_update = 1;
- chown (fname, new_user, new_group);
- } else
- apply_chowns (new_user, new_group);
- break;
- }
-
- if (cpanel->marked && ch_dlg->ret_value != B_CANCEL){
- file_mark (cpanel, current_file, 0);
- cpanel->marked--;
- need_update = 1;
- }
- destroy_dlg (ch_dlg);
- } while (cpanel->marked && !end_chown);
-
- chown_done ();
- }
-